PERL: Пример работы с файлами

#!/usr/bin/perl

 

sub lock_file                 # Функция блокировки файла для предотвращения одновременной записи в него из нескольких процессов

{

 my $handle=shift; # передаем дескриптор файла

 my $time_waut=20; # кол-во циклов ожидания

 until (flock($handle,2)) # ждем, пока файл не освободиться для монопольной блокировки

 {

  sleep(1); # пауза

  if (--$time_wait) {return (0);}

  # если не удалось заблокировать файл за определенное кол-во циклов, выходим из подпрограммы

 }

 return (1); # установлена монопольная блокировка

}

 

$path = '../../data/';            # Путь можно задать отдельно для всех файлов, чтобы проще было корректировать

                                    # Имя файла сделаем изменяемым автоматически, в зависимости от того, что находится в переменной $f

 

$fname = $path.'rezult_'.$f.'.dat'; # Точка обозначает слияние строк

 

if (-e "$fname") # Проверка существования файла с именем, находящимся в $fname

{

 print "Такой файл уже существует и содержит:<br>";

 # открываем файл для чтения

 open(LUBOE_IMYA, "$fname") || die "Не удалось открыть файл $fname";

 unless (&lock_file(LUBOE_IMYA)) # Блокировка файла от доступа других процессов

 {

  print "Не удалось заблокировать файл $fname";

  exit(-1);

 }

 # Читаем из файла построчно

 while ($line = <LUBOE_IMYA>)   # Пока не закончился файл (строка не пустая)

                                                # берем очередную строку из файла и помещаем в $line

 {

  chomp($line);                         # убираем символ конца строки

  print"$line<br>\n";                    # выводим строку в браузер

 }

 close (LUBOE_IMYA); # Закрываем файл и одновременно снимаем блокировку доступа к нему

}

else

{

 print "Файла $fname еще не существует!<br>";

}

 

# открываем файл для дозаписи

 open(LUBOE_IMYA, ">>$fname") || die "Не удалось открыть файл $fname";

# для перезаписи файла было бы: open(LUBOE_IMYA, ">$fname")

 unless (&lock_file(LUBOE_IMYA)) # Блокировка файла от доступа других процессов

 {

  print "Не удалось заблокировать файл $fname";

  exit(-1);

 }

 print ( "$rez\n");

 

 #Печать в файл. Внимание! Запятой нет! Также не забудем в конце \n , иначе строки в файле сольются

 print (LUBOE_IMYA "$op1 $sign $op2 = $rez\n");

 close (LUBOE_IMYA); # Закрываем файл

 

 print "А вдруг ничего не записалось? Проверим!<br>"; # А заодно еще один способ чтения

 # открываем файл для чтения

 open(LUBOE_IMYA, "$fname") || die "Не удалось открыть файл $fname";

 unless (&lock_file(LUBOE_IMYA)) # Блокировка файла от доступа других процессов

 {

  print "Не удалось заблокировать файл $fname";

  exit(-1);

 }

 # Читаем из файла все сразу

 @line = <LUBOE_IMYA>;               # Весь файл в один массив разом

 close (LUBOE_IMYA);                   # Закрываем файл

 chomp(@line);                                     # убираем символ конца строки из всех строк сразу

 $i = 0;

 foreach(@line)                                    # распечатываем весь файл, перебирая строки

 {

  print"$line[$i]<br>\n"; # выводим строку в браузер

  $i++;

 }

 

Из личного опыта.

Считывание файла сразу целиком в массив позволяет быстрее освободить файл для использования его другими процессами. Однако на практике столкнулся с тем, что при изменении содержимого читаемого файла после первого обращения к нему, при всех последующих считываниях файла в массив будет показываться прежняя, а не обновленная информация из файла. Вероятно, это вызвано кэшированием. Поэтому, если файл постоянно обновляется, лучше, все-таки, читать его построчно. Хотя, возможно, то с чем я столкнулся, был эффект конкретного скрипта. Тем не менее, на всякий случай предупреждаю о возможности данного эффекта.

 

Сайт создан в системе